package com.slipper.system.codeless.service;

import java.util.Collections;
import java.util.List;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import com.slipper.util.Tool;
import com.slipper.util.UUID;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;

import com.slipper.system.codeless.dao.PrivilegeDao;
import com.slipper.system.codeless.bo.PrivilegeBO;

import com.slipper.core.transaction.ReadTransactional;
import com.slipper.core.transaction.WriteTransactional;

@Service
@ReadTransactional
public class PrivilegeService {
    @Resource
    private PrivilegeDao privilegeDao;
    @Resource
    private PrivilegeConditionService privilegeConditionService;
    
    public PrivilegeBO queryBy(String id) {
        return privilegeDao.queryBy(id);
    }
    
    public List<PrivilegeBO> queryList(PrivilegeBO bo) {
        return privilegeDao.queryList(bo);
    }
    
    public PageInfo<PrivilegeBO> queryPage(PrivilegeBO bo) {
        PageHelper.startPage(bo.getPageNumber(), bo.getPageSize());
        return new PageInfo<>(privilegeDao.queryList(bo));
    }
    
    @WriteTransactional
    public int save(String sourceId, List<PrivilegeBO> list, String employeeId) {
        if (Tool.isBlank(sourceId)) {
            return 0;
        }

        // 保存/更新数据
        for (PrivilegeBO privilege : list) {
            privilege.setSourceId(sourceId);
            if (Tool.isBlank(privilege.getId())) {
                privilege.setId(UUID.getUUID());
                privilege.setUpdateId(employeeId);
                privilege.setCreateId(employeeId);
                privilege.setUpdateTime(System.currentTimeMillis());
                privilege.setCreateTime(System.currentTimeMillis());
                privilegeDao.insert(privilege);
            } else {
                privilege.setUpdateId(employeeId);
                privilege.setUpdateTime(System.currentTimeMillis());
                privilegeDao.update(privilege);
            }

            privilegeConditionService.save(privilege.getId(), privilege.getConditionList(), employeeId);
        }

        // 删除被删除的数据
        PrivilegeBO qo = new PrivilegeBO();
        qo.setSourceId(sourceId);
        privilegeDao.queryList(qo)
                .stream()
                .filter(privilege -> list.stream().noneMatch(temp -> privilege.getId().equals(temp.getId())))
                .forEach(this::delete);
        return 1;
    }

    @WriteTransactional
    public void saveList(List<PrivilegeBO> list) {
        if (list == null) return;

        list.forEach(item -> {
            if (privilegeDao.queryBy(item.getId()) != null) {
                item.setUpdateTime(System.currentTimeMillis());
                privilegeDao.update(item);
            } else {
                item.setUpdateTime(System.currentTimeMillis());
                item.setCreateTime(System.currentTimeMillis());
                privilegeDao.insert(item);
            }
        });
    }

    @WriteTransactional
    public void copyBySourceId(String oldSourceId, String newSourceId, String employeeId) {
        if (Tool.isBlank(oldSourceId)) {
            return;
        }

        PrivilegeBO qo = new PrivilegeBO();
        qo.setSourceId(oldSourceId);
        privilegeDao.queryList(qo).forEach(privilege -> {
            String oldGroupId = privilege.getId();
            privilege.setId(UUID.getUUID());
            privilege.setSourceId(newSourceId);
            privilege.setUpdateId(employeeId);
            privilege.setCreateId(employeeId);
            privilege.setUpdateTime(System.currentTimeMillis());
            privilege.setCreateTime(System.currentTimeMillis());
            privilegeDao.insert(privilege);

            privilegeConditionService.copyByPrivilegeId(oldGroupId, privilege.getId(), employeeId);
        });
    }

    public List<PrivilegeBO> queryBySourceId(String sourceId) {
        if (Tool.isBlank(sourceId)) {
            return Collections.emptyList();
        }

        PrivilegeBO qo = new PrivilegeBO();
        qo.setSourceId(sourceId);
        List<PrivilegeBO> privilegeList = privilegeDao.queryList(qo);
        privilegeList.forEach(privilege -> privilege.setConditionList(
                privilegeConditionService.queryByPrivilegeId(privilege.getId())));
        return privilegeList;
    }

    @WriteTransactional
    public void deleteBySourceId(String sourceId) {
        if (Tool.isBlank(sourceId)) {
            return;
        }

        PrivilegeBO qo = new PrivilegeBO();
        qo.setSourceId(sourceId);
        privilegeDao.queryList(qo).forEach(this::delete);
    }

    @WriteTransactional
    public void delete(PrivilegeBO bo) {
        if (Tool.isBlank(bo.getId())) {
            return;
        }

        privilegeConditionService.deleteByPrivilegeId(bo.getId());
        privilegeDao.delete(bo);
    }
}
